home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / hardware / GIO_DRVR5.1 / gbd.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  13KB  |  504 lines

  1. /*
  2.  * Copyright (C) 1993, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  */
  5. /* Source for a mythical GIO board device; it can be compiled for
  6.  * devices that support DMA (with or without scatter gather support),
  7.  * or for PIO mode only.  This version is designed for IRIX 5.1 or later.
  8.  * Dave Olson, 5/93
  9. */
  10.  
  11. /* NOTE: compile with cc -coff; kernels can't be in
  12.  * ELF format for now */
  13.  
  14. /* defines for compilation; would normally be passed on compilation
  15.  * line via Makefile */
  16. #define _K32U32     1
  17. #define _KERNEL     1
  18.  
  19. #define IP20     1    /* define cpu type */
  20.  
  21. #if IP20 || IP22
  22. #define R4000    1
  23. #elif IP12
  24. #define R3000    1
  25. #endif
  26.  
  27. /* end of 'normal'  compilation definitions */
  28.  
  29. /* the following definitions choose between PIO vs DMA supporting
  30.  * boards, and if DMA is supported, whether hardware scatter/gather
  31.  * is supported. */
  32. #define GBD_NODMA 0    /* non-zero for PIO version of driver */
  33. #define  GBD_NUM_DMA_PGS  4    /* 0 for no hardware scatter/gather
  34.     * support, else number of pages of scatter/gather
  35.     * supported per request */
  36.  
  37. #include <sys/param.h>
  38. #include <sys/systm.h>
  39. #include <sys/cpu.h>
  40. #include <sys/buf.h>
  41. #include <sys/cred.h>
  42. #include <sys/uio.h>
  43. #include <sys/ddi.h>
  44. #include <sys/errno.h>
  45. #include <sys/cmn_err.h>
  46. #include <sys/edt.h>
  47.  
  48.     /* NOTE: this sample driver ignores the possiblity that
  49.      * the board might be busy handling some earlier request.
  50.      * any real device must deal with that possiblity, of course,
  51.      * before changing the board registers..
  52.      */
  53.  
  54. /* these defines and structures would normally be in a seperate
  55.  * header file */
  56.  
  57. #define GBD_BOARD_ID    0x75
  58. #define GBD_MASK    0xff    /* use 0xff if using only first byte
  59.                  * of ID word, use 0xffff if using
  60.                  * whole ID word
  61.                  */
  62.  
  63. #define GBD_MEMSIZE 0x8000
  64.  
  65. /* command definitions */
  66. #define GBD_GO 1
  67.  
  68. /* state definitions */
  69. #define GBD_SLEEPING 1
  70. #define GBD_DONE 2
  71.  
  72. /* direction of DMA definitions */
  73. #define GBD_READ 0
  74. #define GBD_WRITE 1
  75.  
  76. /* status defines */
  77. #define    GBD_INTR_PEND    0x80
  78.  
  79. /* "gbd" is device prefix; also in master.d/xxx file */
  80.  
  81. /* devices interface to the board */
  82. struct gbd_device {
  83.     int command;
  84.     int count;
  85.     int direction;
  86.     off_t offset;
  87.     unsigned *sgregisters; /* if scatter/gather supported */
  88.     caddr_t startaddr;    /* if no scatter/gather on board */
  89.     unsigned status;    /* errors, interrupt pending, etc. */
  90. };
  91.  
  92.  
  93. /* these are used for no scatter/gather case only, and assume
  94.  * (since they aren't protected!) that the driver is completely
  95.  * single threaded. */
  96. struct buf   *gbd_curbp[2];      /* current buffer */
  97. caddr_t      gbd_curaddr[2];    /* current address to transfer */
  98. int          gbd_curcount[2];
  99. int          gbd_totcount[2];
  100.  
  101. /* pointer to on-board registers */
  102. volatile struct gbd_device *gbd_device[2];
  103.  
  104. char *gbd_memory[2];   /* pointer to on-board memory */
  105.  
  106. static int gbd_state[2];   /* flag for transfer state
  107.                 * (PIO driver) */
  108.  
  109. void gbdintr(int, struct eframe_s *);
  110. extern int splgio1(void);
  111.  
  112. /* early device table initialization routine.  The edt
  113.  * structure is defined in edt.h.
  114.  */
  115. void
  116. gbdedtinit(struct edt *e)
  117. {
  118.     int slot, val;
  119.  
  120.     /* Check to see if the device is present */
  121.     if(badaddr_val(e->e_base, sizeof(int), &val) ||
  122.             (val && GBD_MASK) != GBD_BOARD_ID) {
  123.         if (showconfig)
  124.             cmn_err (CE_CONT,
  125.                 "gbdedtinit: board not installed.");
  126.             return;
  127.     }
  128.  
  129.  
  130.     /* figure out slot from base on VECTOR line in
  131.      * system file */
  132.     if(e->e_base == (caddr_t)0xBF400000)
  133.         slot = GIO_SLOT_0;
  134.     else if(e->e_base == (caddr_t)0xBF600000)
  135.         slot = GIO_SLOT_1;
  136.     else {
  137.         cmn_err (CE_NOTE,
  138.         "ERROR from edtinit: Bad base address %x\n", e->e_base);
  139.         return;
  140.     }
  141.  
  142. #if IP12        /* for Indigo R3000, set up board as a
  143.              * realtime bus master
  144.              */
  145.  
  146.     setgioconfig(slot,0);
  147.  
  148. #endif
  149.  
  150. #if IP20         /* for Indigo R4000, set up board as a
  151.              * realtime bus master
  152.              */
  153.  
  154.     setgioconfig(slot,GIO64_ARB_EXP0_RT | GIO64_ARB_EXP0_MST);
  155.  
  156. #endif
  157.  
  158. #if IP22         /* for Indigo2, set up board as a pipelined,
  159.              * realtime bus master
  160.              */
  161.  
  162.     setgioconfig(slot,GIO64_ARB_EXP0_RT | GIO64_ARB_EXP0_MST);
  163.  
  164. #endif
  165.  
  166.     /* Save the device addresses, because
  167.      * they won't be available later. */
  168.  
  169.     gbd_device[slot == GIO_SLOT_0 ? 0 : 1] =
  170.                 (struct gbd_device *)e->e_base;
  171.     gbd_memory[slot == GIO_SLOT_0 ? 0 : 1] =
  172.                 (char *)e->e_base2;
  173.     setgiovector(GIO_INTERRUPT_1,slot,gbdintr,0);
  174. }
  175.  
  176. /* minor number used to indicate which slot; open does nothing
  177.  * but check that board is present. */
  178. /* ARGSUSED */
  179. gbdopen(dev_t *devp, int flag, int otyp, cred_t *crp)
  180. {
  181.     if(!gbd_device[geteminor(*devp)&1])
  182.         return ENXIO;    /* board not present */
  183.     return 0;    /* OK */
  184. }
  185.  
  186. /* ARGSUSED */
  187. gbdclose(dev_t dev, int flag, int otyp, cred_t *crp)
  188. {
  189.     return 0;    /* nothing to do */
  190. }
  191.  
  192. #ifdef GBD_NODMA
  193.  
  194. /* device write routine entry point (for character devices) */
  195. int
  196. gbdwrite(dev_t dev, uio_t *uio)
  197. {
  198.     int unit = geteminor(dev)&1;
  199.     int size, err=0, s;
  200.  
  201.     /* while there is data to transfer */
  202.     while((size=uio->uio_resid) > 0) {
  203.  
  204.         /* Transfer no more than GBD_MEMSIZE bytes
  205.          * to the device */
  206.         size = size < GBD_MEMSIZE ? size : GBD_MEMSIZE;
  207.  
  208.         /* decrements count and updates uio fields, and copies data */
  209.         if(err=uiomove(gbd_memory[unit], size, UIO_WRITE, uio))
  210.             break;
  211.  
  212.         /* prevent interrupts until we sleep */
  213.         s = splgio1();
  214.  
  215.         /* Transfer is complete; start output */
  216.         gbd_device[unit]->count = size;
  217.         gbd_device[unit]->command = GBD_GO;
  218.         gbd_state[unit] = GBD_SLEEPING;
  219.         while (gbd_state[unit] != GBD_DONE) {
  220.             sleep(&gbd_state[unit], PRIBIO);
  221.         }
  222.         /* restore the process level after waking up */
  223.         splx(s);
  224.     }
  225.     return err;
  226. }
  227.  
  228.  
  229. /* interrupt routine for PIO only board, just wake up
  230.  * upper half of driver
  231.  */
  232. /* ARGSUSED1 */
  233. void
  234. gbdintr(int unit, struct eframe_s *ef)
  235. {
  236.     /* read your board's registers to determine if
  237.      * there are any errors or interrupts pending.
  238.      * If no interrupts are pending, return without
  239.      * doing anything.
  240.      */
  241.     if(!gbd_device[unit]->status & GBD_INTR_PEND)
  242.         return;
  243.  
  244.     if (gbd_state[unit] == GBD_SLEEPING) {
  245.         /* Output is complete; wake up top half
  246.          * of driver, if it is waiting */
  247.         gbd_state[unit] = GBD_DONE;
  248.         wakeup(&gbd_state[unit]);
  249.     }
  250.  
  251.     /* do anything else to board to tell it we are done
  252.      * with transfer and interrupt here */
  253. }
  254.  
  255. #else    /* DMA version of driver */
  256.  
  257. void gbd_strategy(struct buf *);
  258.  
  259. /* device write routine entry point (for character devices).
  260.  * Does nothing but call uiophysio to to setup, passing a pointer
  261.  * to the gbd_strategy routine, which does most of the work.
  262. */
  263. int
  264. gbdwrite(dev_t dev, uio_t *uiop)
  265. {
  266.     return uiophysio((int (*)())gbd_strategy, 0, dev, B_WRITE, uiop);
  267. }
  268.  
  269. #if GBD_NUM_DMA_PGS > 0
  270.  
  271. /* Actual device setup for DMA, etc., if your board has
  272.  * hardware scatter/gather DMA support.
  273.  * Called from the gbdwrite() routine via physio().
  274.  */
  275. void
  276. gbd_strategy(struct buf *bp)
  277. {
  278.     int unit = geteminor(bp->b_dev)&1;
  279.     int npages;
  280.     volatile unsigned *sgregisters;
  281.     int i, v_addr;
  282.  
  283.     /* Get address of the scatter-gather registers */
  284.      *sgregisters = gbd_device[unit]->sgregisters;
  285.  
  286.     /* Get the kernel virtual address of the data; note
  287.      * b_dmaaddr may be NULL if the  BP_ISMAPPED(bp) macro
  288.      * indicates false; in that case, the field bp->b_pages
  289.      * is a pointer to a linked list of pfdat structure
  290.      * pointers; that saves creating a virtual mapping and
  291.      * then decoding that mapping back to physical addresses.
  292.      * BP_ISMAPPED will never be false for character devices,
  293.      * only block devices.
  294.      */
  295.      if(!BP_ISMAPPED(bp)) {
  296.         cmn_err(CE_WARN,
  297.             "gbd driver can't handle unmapped buffers");
  298.         bp->b_flags |= B_ERROR;
  299.         iodone(bp);
  300.         return;
  301.     }
  302.  
  303.     v_addr = bp->b_dmaaddr;
  304.  
  305.     /* Compute number of pages received.
  306.      * The dma_len field provides the number of pages to
  307.      * map. Note that this may be larger than the actual
  308.      * number of bytes involved in the transfer. This is
  309.      * because the transfer may cross page boundaries,
  310.      * requiring an extra page to be mapped.  Limit to
  311.      * number of scatter/gather registers on board.
  312.      * Note that this sample driver doesn't handle the
  313.      * case of requests > than # of registers!
  314.      */
  315.     npages = numpages (v_addr, bp->b_dmalen);
  316.     /*
  317.      * Provide the beginning byte offset and count to the
  318.      * device.
  319.      */
  320.     gbd_device[unit]->offset =
  321.             (unsigned int)bp->b_dmaaddr & (NBPC-1);
  322.     if(npages > GBD_NUM_DMA_PGS) {
  323.          npages = GBD_NUM_DMA_PGS;
  324.         cmn_err(CE_WARN,
  325.             "request too large, only %d pages max", npages);
  326.         if(gbd_device[unit]->offset)
  327.             gbd_device[unit]->count = NBPC -
  328.                 gbd_device[unit]->offset + (npages-1)*NBPC;
  329.         else
  330.             gbd_device[unit]->count = npages*NBPC;
  331.         bp->b_resid = bp->b_count - gbd_device[unit]->count;
  332.     }
  333.     else
  334.         gbd_device[unit]->count = bp->b_count;
  335.  
  336.     /* Translate the virtual address of each page to a
  337.      * physical page number and load it into the next
  338.      * scatter-gather register.  The btoct(K) macro
  339.      * converts the byte value to a page value after
  340.      * rounding down the byte value to a full page.
  341.      */
  342.      for (i = 0; i < npages; i++) {
  343.         *sgregisters++ = btoct(kvtophys(v_addr));
  344.  
  345.         /*
  346.         /* Get the next virtual address to translate.
  347.          * (NBPC is a symbolic constant for the page
  348.          * size in bytes)
  349.          */
  350.  
  351.         v_addr += NBPC;
  352.     }
  353.  
  354.     if ((bp->b_flags & B_READ) == 0)
  355.         gbd_device[unit]->direction = GBD_WRITE;
  356.     else
  357.         gbd_device[unit]->direction = GBD_READ;
  358.     gbd_device[unit]->command = GBD_GO;    /* start DMA */
  359.  
  360.     /* and return; upper layers of kernel wait for iodone(bp) */
  361. }
  362.  
  363.  
  364. /* not much to do in this interrupt routine, since we are
  365.  * assuming for this driver that we can never have to do
  366.  * multiple DMA's to handle the number of bytes requested...
  367.  */
  368. void
  369. gbdintr(int unit)
  370. {
  371.     int error;
  372.  
  373.     /* read your board's registers to determine if
  374.      * there are any errors or interrupts pending.
  375.      * If no interrupts are pending, return without
  376.      * doing anything.
  377.      */
  378.     if(!gbd_device[unit]->status & GBD_INTR_PEND)
  379.         return;
  380.  
  381.     if(error)
  382.         bp->b_flags |= B_ERROR;
  383.  
  384.     iodone(bp);    /* we are done, tell upper layers */
  385.  
  386.     /* do anything else to board to tell it we are done
  387.      * with transfer and interrupt here */
  388. }
  389.  
  390. #else /*  GBD_NUM_DMA_PGS == 0; no hardware
  391.        *  scatter/gather support */
  392.  
  393. /* Actual device setup for DMA, etc., if your board
  394.  * does NOT have hardware scatter/gather DMA support.
  395.  * Called from the gbdwrite() routine via physio().
  396.  */
  397. void
  398. gbd_strategy(struct buf *bp)
  399. {
  400.     int unit = geteminor(bp->b_dev)&1;
  401.  
  402.     /* any checking for initial state here. */
  403.  
  404.     /* Get the kernel virtual address of the data; note
  405.      * b_dmaaddr may be NULL if the  BP_ISMAPPED(bp) macro
  406.      * indicates false; in that case, the field bp->b_pages
  407.      * is a pointer to a linked list of pfdat structure
  408.      * pointers; that saves creating a virtual mapping and
  409.      * then decoding that mapping back to physical addresses.
  410.      * BP_ISMAPPED will never be false for character devices,
  411.      * only block devices.
  412.      */
  413.      if(!BP_ISMAPPED(bp)) {
  414.         cmn_err(CE_WARN,
  415.             "gbd driver can't handle unmapped buffers");
  416.         bp->b_flags |= B_ERROR;
  417.         iodone(bp);
  418.         return;
  419.     }
  420.  
  421.     gbd_curbp[unit] = bp;
  422.     /*
  423.      * Initialize the current transfer address and count.
  424.      * The first transfer should finish the rest of the
  425.      * page, but do no more than the total byte count.
  426.      */
  427.     gbd_curaddr[unit] = bp->b_dmaaddr;
  428.     gbd_totcount[unit] = bp->b_count;
  429.     gbd_curcount[unit] = NBPC -
  430.         ((unsigned int)gbd_curaddr[unit] & (NBPC-1));
  431.     if (bp->b_count < gbd_curcount[unit])
  432.         gbd_curcount[unit] = bp->b_count;
  433.     /* Tell the device starting physical address, count,
  434.      * and direction */
  435.     gbd_device[unit]->startaddr = kvtophys(gbd_curaddr[unit]);
  436.     gbd_device[unit]->count = gbd_curcount[unit];
  437.     if (bp->b_flags & B_READ) == 0)
  438.         gbd_device[unit]->direction = GBD_WRITE;
  439.     else
  440.         gbd_device[unit]->direction = GBD_READ;
  441.     gbd_device[unit]->command = GBD_GO;    /* start DMA */
  442.  
  443.     /* and return; upper layers of kernel wait for iodone(bp) */
  444. }
  445.  
  446.  
  447. /* more complicated interrupt routine, not necessarily because
  448.  * board has DMA, but more typical of boards that do have
  449.  * DMA, since they are typically more complicated.
  450.  * Also more typical of devices that support block i/o, as
  451.  * opposed to character i/o.
  452.  */
  453. void
  454. gbdintr(int unit)
  455. {
  456.     int error;
  457.     register struct buf *bp = gbd_curbp[unit];
  458.  
  459.     /* read your board's registers to determine if
  460.      * there are any errors or interrupts pending.
  461.      * If no interrupts are pending, return without
  462.      * doing anything.
  463.      */
  464.     if(!gbd_device[unit]->status & GBD_INTR_PEND)
  465.         return;
  466.  
  467.     if(error) {
  468.         bp->b_flags |= B_ERROR;
  469.         iodone(bp);    /* we are done, tell upper layers */
  470.     }
  471.     else {
  472.         /* On successful transfer of last chunk, continue
  473.          * if necessary */
  474.         gbd_curaddr[unit] += gbd_curcount[unit];
  475.         gbd_totcount[unit] -= gbd_curcount[unit];
  476.         if(gbd_totcount[unit] <= 0)
  477.             iodone(bp);
  478.                 /* we are done, tell upper layers */
  479.         else {
  480.         /* else more to do, reprogram board and
  481.          * start next dma */
  482.         gbd_curcount[unit] =
  483.             (gbd_totcount[unit] < NBPC
  484.                     ? gbd_totcount[unit] : NBPC);
  485.         gbd_device[unit]->startaddr =
  486.                     kvtophys(gbd_curaddr[unit]);
  487.         gbd_device[unit]->count = gbd_curcount[unit];
  488.         if (bp->b_flags & B_READ) == 0)
  489.             gbd_device[unit]->direction = GBD_WRITE;
  490.         else
  491.             gbd_device[unit]->direction = GBD_READ;
  492.         gbd_device[unit]->command = GBD_GO;
  493.                     /* start next DMA */
  494.         }
  495.     }
  496.  
  497.     /* do anything else to board to tell it we are done
  498.      * with transfer and interrupt here */
  499. }
  500. #endif /*  GBD_NUM_DMA_PGS */
  501.  
  502. #endif /* GBD_NODMA */
  503.  
  504.